package com.gs.netty.support.handler.adapter;

import com.gs.netty.core.handler.method.HandlerMethod;
import com.gs.netty.core.resolver.HandlerMethodReturnValueHandler;
import com.gs.netty.support.resolver.HandlerMethodReturnValueHandlerComposite;
import com.gs.netty.core.resolver.args.HandlerMethodArgumentResolver;
import com.gs.netty.support.resolver.HandlerMethodArgumentResolverComposite;
import com.gs.netty.support.handler.method.InvocableHandlerMethod;

import com.gs.netty.websocket.remoting.req.NativeWebSocketRequest;
import com.gs.netty.websocket.remoting.req.SocketRequest;
import com.gs.netty.websocket.remoting.resp.SocketResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.List;
import java.util.Map;

/**
 * 指令映射适配处理器
 */

public class WebSocketCommandMappingHandlerAdapter extends AbstractHandlerAdapter<SocketRequest, SocketResponse,HandlerMethod> implements ApplicationContextAware {

    private static final Logger log = LoggerFactory.getLogger(WebSocketCommandMappingHandlerAdapter.class);
    private ApplicationContext applicationContext;

    @Override
    public void handle(SocketRequest request, SocketResponse response, HandlerMethod handler) throws Throwable {

        if (handler.isEventHandler()) {
            log.error("No handler found for request command: "+ request.getCommand());
            return;
        }


        NativeWebSocketRequest nativeRequest = new NativeWebSocketRequest(request,response);
        InvocableHandlerMethod invocableHandlerMethod = new InvocableHandlerMethod(handler);
        // 设置参数解析器
        if (argumentResolvers != null) {
            invocableHandlerMethod.setArgumentResolvers(argumentResolvers);
        }

        // 设置结果处理器
        if (this.returnValueHandlers != null) {
            invocableHandlerMethod.setReturnValueHandlers(this.returnValueHandlers);
        }

        // 代码执行
         invocableHandlerMethod.invokeAndHandle(nativeRequest);
    }

    @Override
    public boolean support(Object o) {
        return HandlerMethod.class.isAssignableFrom(o.getClass());
    }
    @Override
    protected void initArgumentResolvers() {
        if (this.argumentResolvers == null) {
            // 获取默认的参数处理器
            List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();

            Map<String, HandlerMethodArgumentResolver> argumentResolverMap =
                    BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, HandlerMethodArgumentResolver.class, true, false);
            if (!argumentResolverMap.isEmpty()) {
                resolvers.addAll(argumentResolverMap.values());
            }
            // 添加自定义的参数处理器
            this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addArgumentResolvers(resolvers);
        }
    }

    @Override
    protected void initReturnValueHandlers() {
        if (this.returnValueHandlers == null) {
            // 获取默认的参数处理器
            List<HandlerMethodReturnValueHandler> resolvers = getDefaultReturnValueHandlers();

            Map<String, HandlerMethodReturnValueHandler> argumentResolverMap =
                    BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, HandlerMethodReturnValueHandler.class,
                            true, false);
            if (!argumentResolverMap.isEmpty()) {
                resolvers.addAll(argumentResolverMap.values());
            }
            // 添加自定义的参数处理器
            this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(resolvers);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
